package trb.complexshield.benchmarking;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.vecmath.Point3i;
import no.hrp.hvrc.property.PropertyOwner;

//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 21, 24, 28, 32, 37, 43, 49, 56
// , 64, 74, 85, 98, 113, 130, 150, 173, 199, 229, 263, 302, 347, 399, 459, 528, 607, 698, 803, 923]

//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 23, 25, 28, 31
// , 34, 37, 41, 45, 50, 55, 61, 67, 74, 81, 89, 98, 108, 119, 131, 144, 158, 174
// , 191, 210, 231, 254, 279, 307, 338, 372, 409, 450, 495, 545, 600, 660, 726, 799, 879, 967]

//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
// , 23, 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 53
// , 56, 59, 62, 65, 68, 71, 75, 79, 83, 87, 91, 96, 101, 106, 111, 117, 123, 129
// , 135, 142, 149, 156, 164, 172, 181, 190, 200, 210, 221, 232, 244, 256, 269
// , 282, 296, 311, 327, 343, 360, 378, 397, 417, 438, 460, 483, 507, 532, 559
// , 587, 616, 647, 679, 713, 749, 786, 825, 866, 909, 954, 1002]


public class BenchmarkVoxels {

    public static final String VOXEL_PATH = "C:\\Users\\tomrbryn.000\\Documents\\master\\project\\excel\\voxelData.xml";

    public static void main(String[] args) {
        benchmarkVoxels();
        System.out.println(generateTable((owner) -> {
            return ("" + ((BenchmarkOutput) owner).getErrorPerc() / 100f).replace(".", ",");
        }));
        System.out.println(generateTable((owner) -> {
            BenchmarkOutput output = (BenchmarkOutput) owner;
            Point3i dims = output.voxelDims.get();
            int cellCount = dims.x + dims.y + dims.z;
            return ("" + output.timeNano.get()/1E9).replace(".", ",");
        }));
    }

    public static void benchmarkVoxels() {
        List<Integer> voxelDims = new ArrayList();
        int voxelDim = 1;
        while (voxelDim < 1024) {
            voxelDims.add(voxelDim);
            voxelDim += Math.max(1, Math.round(voxelDim * .05));
        }
        int[] voxelDimInts = new int[voxelDims.size()];
        for (int i=0; i<voxelDimInts.length; i++) {
            voxelDimInts[i] = voxelDims.get(i);
        }
        BenchmarkAll.Settings settings = new BenchmarkAll.Settings(false, false, true, 1, 2, voxelDimInts);

        List<BenchmarkOutput> outputs = new ArrayList<>();
        outputs.addAll(BenchmarkAll.benchmarkBoxes(settings));
        outputs.addAll(BenchmarkAll.benchmarkSpheres(settings));
        outputs.addAll(BenchmarkAll.benchmarkTubs(settings));
        outputs.addAll(BenchmarkAll.benchmarkRooms(settings));
        outputs.addAll(BenchmarkAll.benchmarkTubes(settings));

        File file = new File(VOXEL_PATH);
        BenchmarkAll.writeStringToFile(file, BenchmarkAll.benchmarkOutputListToString(outputs));
    }

    public static String generateTable(Function<PropertyOwner, String> ownerPropertyToString) {
        List<BenchmarkOutput> outputs = BenchmarkAll.benchmarkOutputListFromString(
                BenchmarkAll.readStringFromFile(new File(VOXEL_PATH)));

        Map<Integer, Map<String, String>> dimShapeResultMap = new HashMap<>();
        for (BenchmarkOutput output : outputs) {
            Integer voxelDim = output.voxelDim.get();
            if (voxelDim > 0) {
                Map<String, String> shapeResultMap = dimShapeResultMap.get(voxelDim);
                if (shapeResultMap == null) {
                    shapeResultMap = new HashMap<>();
                    dimShapeResultMap.put(voxelDim, shapeResultMap);
                }
                String string = ownerPropertyToString.apply(output);
                if (string != null) {
                    shapeResultMap.put(output.shapeName.get(), string);
                }
            }
        }

        ArrayList<Integer> sortedDims = new ArrayList(dimShapeResultMap.keySet());
        Collections.sort(sortedDims);

        StringBuilder str = new StringBuilder();
        str.append("dim ");
        for (String shapeName : BenchmarkAll.SHAPE_NAMES) {
            str.append(shapeName).append(" ");
        }
        str.append("\n");

        for (Integer sortedDim : sortedDims) {
            str.append(sortedDim).append(" ");
            Map<String, String> shapeResultMap = dimShapeResultMap.get(sortedDim);
            for (String shapeName : BenchmarkAll.SHAPE_NAMES) {
                str.append(shapeResultMap.get(shapeName)).append(" ");
            }
            str.append("\n");
        }
        return str.toString();
    }
}
